/**
 * 
 */
package com.dalonedrow.module.chivalrysorcery.systems;

import com.dalonedrow.engine.systems.base.Interactive;
import com.dalonedrow.module.chivalrysorcery.rpg.ChivSorcInteractiveObject;
import com.dalonedrow.module.chivalrysorcery.rpg.ChivSorcInventoryData;
import com.dalonedrow.pooled.PooledStringBuilder;
import com.dalonedrow.pooled.StringBuilderPool;

/**
 * @author Donald
 */
public final class ChivSorcInteractive extends Interactive<ChivSorcInteractiveObject> {
	/** the list of {@link HQChivSorcInteractiveObject}s. */
	private ChivSorcInteractiveObject[]	objs;
	/** Creates a new instance of {@link ChivSorcInteractive}. */
	ChivSorcInteractive() {
		Interactive.setInstance(this);
		objs = new ChivSorcInteractiveObject[0];
		nextId = 0;
	}
	@Override
	public void addAnimation(final int id, final int animId) throws Exception {
		ChivSorcInteractiveObject io = getIO(id);
		if (io == null) {
			PooledStringBuilder sb = StringBuilderPool.getInstance()
					.getStringBuilder();
			sb.append("ERROR! Interactive.addAnimation() - ");
			sb.append("id '");
			sb.append(id);
			sb.append("' has no valid InteractiveObject");
			Exception ex = new Exception(sb.toString());
			sb.returnToPool();
			throw ex;
		}
	}
	@Override
	public ChivSorcInteractiveObject getIO(final int id) {
		ChivSorcInteractiveObject io = null;		
		if (hasIO(id)) {
			for (int i = 0; i < objs.length; i++) {
				if (objs[i] != null
						&& objs[i].getRefId() == id) {
					io = objs[i];
					break;
				}
			}
		}
		return io;
	}
	/** the next available id. */
	private int nextId;
	/**
	 * {@inheritDoc}
	 */
	@Override
	public ChivSorcInteractiveObject getNewIO() {
		// step 1 - find the next id
		int id = nextId++;
		// step 2 - find the next available index in the objs array
		int index = -1;
		for (int i = 0; i < objs.length; i++) {
			if (objs[i] == null) {
				index = i;
				break;
			}
		}
		// step 3 - put the new object into the arrays
		if (index == -1) {
			// no room, extend the array
			index = objs.length;
			ChivSorcInteractiveObject[] dest =
					new ChivSorcInteractiveObject[objs.length + 1];
			System.arraycopy(objs, 0, dest, 0, objs.length);
			objs = dest;
			dest = null;
		}
		// step 4 - put the IO into the array
		ChivSorcInteractiveObject io = new ChivSorcInteractiveObject(id);
		objs[index] = io;
		return io;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public int getNumberIOs() {
		int num = 0;
		for (int i = 0; i < objs.length; i++) {
			if (objs[i] != null) {
				num++;
			}
		}
		return num;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean hasIO(final int id) {
		boolean has = false;
		for (int i = 0; i < objs.length; i++) {
			if (objs[i] != null
					&& id == objs[i].getRefId()) {
				has = true;
				break;
			}
		}
		return has;
	}
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void releaseIO(ChivSorcInteractiveObject io) {
		if (io != null) {
			ChivSorcScript.getInstance().timerClearForIO(io);
			ChivSorcSpells.getInstance().removeAllSpellsOn(io);
			if (io.getInventory() != null) {
				ChivSorcInventoryData inventory = io.getInventory();
				if (inventory != null) {
					for (int j = 0; j < inventory.getNumInventorySlots(); j++) {
						if (io.equals(inventory.getSlot(j).getIo())) {
							inventory.getSlot(j).setIo(null);
							inventory.getSlot(j).setShow(true);
						}
					}
				}
			}
			ChivSorcScript.getInstance().releaseScript(io.getScript());
			ChivSorcScript.getInstance().releaseScript(io.getOverscript());
			ChivSorcScript.getInstance().releaseAllGroups(io);
			int id = io.getRefId();
			int index = -1;
			for (int i = 0; i < objs.length; i++) {
				if (objs[i] != null
						&& id == objs[i].getRefId()) {
					index = i;
					break;
				}
			}
			if (index > -1) {
				objs[index] = null;
			}
			io = null;
		}
	}
}
